﻿
#region Using Directives.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Windows.Forms;
using System.IO;
using BrightIdeasSoftware;
using GDFlacTool.Client;
using GDFlacTool.Client.Forms;
using GDFlacTool.Common;
using GDFlacTool.Forms;
using GDFlacTool.Properties;
using GDFlacTool.forms;
using LogicNP.FolderViewControl;
using ShellLib;

#endregion

namespace GDFlacTool
{
    public partial class FormFlacTool : Form
    {
        #region Fields.

        private readonly TrackCollection _trackCollectiontracks = new TrackCollection();
        private readonly TypedObjectListView<Track> _trackList;
        private string _currentPath = String.Empty;
        private bool _cancelSorting;
        private bool _resetMultiTagEditor = true;
        //private OLVColumn _sortedColumn;
        //private SortOrder _sortOrder = SortOrder.None;
        protected MruStripMenuInline MruMenu;
        private readonly string _fileList = string.Empty;
        private DragDropEffects _dragDropEffects = DragDropEffects.None;
        private StringCollection _editors = new StringCollection();
        private string _currentEditor = string.Empty;
        private string _currentExtension = string.Empty;
        private readonly EventHandler handler;
        private string _webUrl = string.Empty;
        private int _timerCount = 1;

        #endregion

        #region Constructors.

        public FormFlacTool()
        {
            InitializeComponent();

            handler = (FormFlacTool_Activated);

            Activated -= handler;

            Width = MainSettings.Default.FormWidth;

            Height = MainSettings.Default.FormHeight;

            WindowState = (FormWindowState)MainSettings.Default.WindowState;

            objectListView.UseAlternatingBackColors = true;

            objectListView.AlternateRowBackColor = Color.FromArgb(204, 255, 255);

            objectListView.BackColor = Color.FromArgb(255, 255, 255);

            objectListView.DragSource = new TrackDragObject();

            _trackList = new TypedObjectListView<Track>(objectListView);

            tabMain.SelectedIndex = MainSettings.Default.SelectedTab;

            //_sortedColumn = objectListView.PrimarySortColumn;

            //_sortOrder = objectListView.PrimarySortOrder;
            
            //if (MainSettings.Default.SecondSortedColumn != null)
            //{
            //    objectListView.SecondarySortColumn = GetSecondSortingColumnFromMenu(MainSettings.Default.SecondSortedColumn);
            //}
            //else
            //{
            //    objectListView.SecondarySortColumn = olvColumnFilename;
            //}

            //objectListView.sort

            //objectListView.PrimarySortOrder = MainSettings.Default.SortOrder;

            //_secondarySortOrder = MainSettings.Default.SecondSortOrder;

            //objectListView.SecondarySortOrder = MainSettings.Default.SecondSortOrder;

            //CreateSecondarySortColumnMenu(objectListView.SecondarySortColumn);
            
            _fileList = MainSettings.Default.RecentFiles;

            LoadArtistCombo();

            LoadGenreCombo();

            LoadFileRenameMaskCombo();

            LoadTagFromFileMaskCombo();

            MruMenu = new MruStripMenuInline(tsbRecentFolders, mruRecentFiles, OnMruFile, 16, 96);
        }

        #endregion

        #region Form Events.

        private void FormMain_Load(object sender, EventArgs e)
        {
            byte[] setting = MainSettings.Default.ObjectListViewStat;

            if (setting != null)
            {
                objectListView.RestoreState(setting);

                if (MainSettings.Default.PrimarySortColumn != null)
                {
                    objectListView.PrimarySortColumn = GetSortingColumnFromName(MainSettings.Default.PrimarySortColumn);
                }
                else
                {
                    objectListView.PrimarySortColumn = olvColumnFilename;
                }

                if (MainSettings.Default.SecondarySortColumn != null)
                {
                    objectListView.SecondarySortColumn = GetSortingColumnFromName(MainSettings.Default.SecondarySortColumn);
                }
                else
                {
                    objectListView.SecondarySortColumn = olvColumnFilename;
                }

                objectListView.PrimarySortOrder = MainSettings.Default.PrimarySortOrder;
                objectListView.SecondarySortOrder = MainSettings.Default.SecondarySortOrder;
            }
            else
            {
                objectListView.PrimarySortColumn = olvColumnFilename;
                objectListView.PrimarySortOrder = SortOrder.Ascending;
                objectListView.SecondarySortColumn = olvColumnFilename;
                objectListView.SecondarySortOrder = SortOrder.Ascending;
            }

            CreateSecondarySortColumnMenu(objectListView.SecondarySortColumn);
            
            chkReplaceRename.Checked = MainSettings.Default.ChkRenameUnderscoresChecked;
            chkReplaceTagsFromFile.Checked = MainSettings.Default.ChkTagsFromFileUnderscoresChecked;
            ucCaseRename.CaseChecked = MainSettings.Default.UcCaseRenameChecked;
            ucCaseRename.Case = (CaseType)MainSettings.Default.UcCaseRenameTypeSelected;
            ucCaseMultiTag.CaseChecked = MainSettings.Default.UcCaseMultiTagChecked;
            ucCaseMultiTag.Case = (CaseType)MainSettings.Default.UcCaseMultiTagTypeSelected;
            ucCaseTagsFromFile.CaseChecked = MainSettings.Default.UcCaseTagsFromFileChecked;
            ucCaseTagsFromFile.Case = (CaseType)MainSettings.Default.UcCaseTagsFromFileTypeSelected;
            _editors = MainSettings.Default.AddedImageEditors ?? new StringCollection();

            _currentEditor = MainSettings.Default.CurrentImageEditor;

            if (!String.IsNullOrEmpty(MainSettings.Default.FolderViewStartFolder))
            {
                flvTagEditor.BeginUpdate();
                flvTagEditor.SelectNode(MainSettings.Default.FolderViewStartFolder, true);
                flvTagEditor.RefreshTree();
                flvTagEditor.EndUpdate(false);
            }

            if (!string.IsNullOrEmpty(_fileList))
            {
                MruMenu.LoadFromString(_fileList);
                tsbRecentFolders.Enabled = true;
            }

            if (!string.IsNullOrEmpty(MainSettings.Default.LastRenameMask))
            {
                if (cboMaskRename.Items.IndexOf(MainSettings.Default.LastRenameMask) >= 0)
                {
                    cboMaskRename.SelectedIndex = cboMaskRename.Items.IndexOf(MainSettings.Default.LastRenameMask);
                }
                else
                {
                    cboMaskRename.Text = MainSettings.Default.LastRenameMask;
                }
            }

            if (!string.IsNullOrEmpty(MainSettings.Default.LastTagFromFileMask))
            {
                if (cboMaskTagsFromFile.Items.IndexOf(MainSettings.Default.LastTagFromFileMask) >= 0)
                {
                    cboMaskTagsFromFile.SelectedIndex = cboMaskTagsFromFile.Items.IndexOf(MainSettings.Default.LastTagFromFileMask);
                }
                else
                {
                    cboMaskTagsFromFile.Text = MainSettings.Default.LastTagFromFileMask;
                }
            }

            Activated += handler;
        }

        private void FormFlacTool_Activated(object sender, EventArgs e)
        {
            if (!Directory.Exists(_currentPath))
            {
                flvTagEditor.RefreshTree();
                _currentPath = flvTagEditor.SelectedNode.Path;
                RefreshTrackList(_currentPath);
            }
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            MainSettings.Default.SelectedTab = tabMain.SelectedIndex;
            MainSettings.Default.FolderViewStartFolder = _currentPath;
            MainSettings.Default.ObjectListViewStat = objectListView.SaveState();
            MainSettings.Default.LastRenameMask = cboMaskRename.Text;
            MainSettings.Default.LastTagFromFileMask = cboMaskTagsFromFile.Text;
            MainSettings.Default.ChkRenameUnderscoresChecked = chkReplaceRename.Checked;
            MainSettings.Default.ChkTagsFromFileUnderscoresChecked = chkReplaceTagsFromFile.Checked;
            MainSettings.Default.UcCaseRenameChecked = ucCaseRename.CaseChecked;
            MainSettings.Default.UcCaseRenameTypeSelected = (int)ucCaseRename.GetCaseType();
            MainSettings.Default.UcCaseMultiTagChecked = ucCaseMultiTag.CaseChecked;
            MainSettings.Default.UcCaseMultiTagTypeSelected = (int)ucCaseMultiTag.GetCaseType();
            MainSettings.Default.UcCaseTagsFromFileChecked = ucCaseTagsFromFile.CaseChecked;
            MainSettings.Default.UcCaseTagsFromFileTypeSelected = (int)ucCaseTagsFromFile.GetCaseType();
            MainSettings.Default.RecentFiles = MruMenu.SaveToString();
            MainSettings.Default.AddedImageEditors = _editors;
            MainSettings.Default.CurrentImageEditor = _currentEditor;
            MainSettings.Default.FormWidth = Width;
            MainSettings.Default.FormHeight = Height;
            MainSettings.Default.WindowState = (int)WindowState;

            if (objectListView.PrimarySortColumn != null)
            {
                MainSettings.Default.SecondarySortColumn = objectListView.SecondarySortColumn.Tag.ToString();
                MainSettings.Default.PrimarySortColumn = objectListView.PrimarySortColumn.Tag.ToString();
                MainSettings.Default.PrimarySortOrder = objectListView.PrimarySortOrder;
                MainSettings.Default.SecondarySortOrder = objectListView.SecondarySortOrder;
            }

            MainSettings.Default.Save();
        }

        #endregion

        #region FolderView & shComboBox Events.

        private void flvTagEditor_AfterSelect(object sender, FolderViewEventArgs e)
        {
            EnableEditControlsFromCheckedItems(false);

            btnUndo.Enabled = false;

            _currentPath = e.Node.Path;

            Text = string.Format("GD Flac Tool - [{0}]", Functions.ShortenName(_currentPath, 200));

            shcTagEditor.SetPath(e.Node.Path);

            RefreshTrackList(e.Node.Path);

            UpdateStatusbar(_trackList.Objects.Count, _trackList.CheckedObjects.Count,
                            CalculateTrackTime(_trackList.Objects), CalculateTrackTime(_trackList.CheckedObjects),
                            CalculateSelectedTrackSize(_trackList.CheckedObjects),
                            CalculateArt(_trackList.CheckedObjects));
        }

        private void shcTagEditor_ItemSelected(object Sender, EventArgs e)
        {
            flvTagEditor.SelectNode(shcTagEditor.SelectedItem.Path, false);
        }

        #endregion

        #region FolderView Toolbar Events.

        private void tsbMoveUp_Click(object sender, EventArgs e)
        {
            flvTagEditor.GoUp();
        }

        private void tsbRefreshFolders_Click(object sender, EventArgs e)
        {
            flvTagEditor.RefreshTree();
        }

        private void tmuNewFolder_Click(object sender, EventArgs e)
        {
            flvTagEditor.GoUp();

            FOVTreeNode node = flvTagEditor.CreateNewFolder(true);

            flvTagEditor.SelectedNode = node;
        }

        private void tmuNewSubFolder_Click(object sender, EventArgs e)
        {
            FOVTreeNode node = flvTagEditor.CreateNewFolder(true);

            flvTagEditor.SelectedNode = node;
        }

        private void OnMruFile(int number, string path)
        {
            if (Directory.Exists(path))
            {
                flvTagEditor.SelectNode(path, false);
            }
            else
            {
                string message = string.Format(
                    "The folder: {0} can not be  and will be removed from the Recent list(s)",
                    Path.GetDirectoryName(path));

                MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                MruMenu.RemoveFile(number);

                if (MruMenu.MenuItems.Count == 0)
                {
                    tsbRecentFolders.Enabled = false;
                }
            }
        }

        #endregion

        #region Menu Events.

        #region File Menu.

        private void mnuOpen_Click(object sender, EventArgs e)
        {
            OpenFolder();
        }

        private void mnuSaveTags_Click(object sender, EventArgs e)
        {
            SaveTags();
        }

        private void mnuRemoveTags_Click(object sender, EventArgs e)
        {
            RemoveTags();
        }

        private void mnuMoveFileDown_Click(object sender, EventArgs e)
        {
            MoveFileDown();
        }

        private void mnuMoveFileUp_Click(object sender, EventArgs e)
        {
            MoveFileUp();
        }

        private void mnuCopyTag_Click(object sender, EventArgs e)
        {
            if (_trackList.SelectedObjects.Count > 0)
            {
                Track track = _trackList.SelectedObjects[0];

                ClipBoard.SetObject(track);

                mnuPasteTag.Enabled = true;
                mnuPasteTagToAllSelectedFiles.Enabled = true;
                mnuClearClipboard.Enabled = true;
            }
        }

        private void mnuClearClipboard_Click(object sender, EventArgs e)
        {
            if (ClipBoard.ContainsObject())
            {
                ClipBoard.Clear();
                mnuPasteTag.Enabled = false;
                mnuPasteTagToAllSelectedFiles.Enabled = false;
                mnuClearClipboard.Enabled = false;
            }
        }

        private void mnuPasteTagToAllSelectedFiles_Click(object sender, EventArgs e)
        {
            int progress = 0;
            int total = _trackList.CheckedObjects.Count;

            if (total < 1)
                return;

            var frm = new FormPasteTag(_trackList.CheckedObjects.Count);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                if (ClipBoard.ContainsObject() && ClipBoard.GetObjectType() == typeof(TrackFlac))
                {
                    foreach (Track track in _trackList.CheckedObjects)
                    {
                        PasteTag(track, frm.DontPasteTitleField, frm.DontPasteTrackField, frm.DontPasteDiscField, frm.DontPasteBpmField,
                        frm.DontPasteLyricsField, frm.DontPasteArtistField);

                        sblProgress.Value = ++progress * 100 / total;


                    }

                    _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

                    sblProgress.Value = 0;
                }
            }
        }

        private void mnuPasteTag_Click(object sender, EventArgs e)
        {
            if (_trackList.SelectedObjects.Count < 1)
                return;

            var frm = new FormPasteTag(1);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                if (ClipBoard.ContainsObject() && ClipBoard.GetObjectType() == typeof(TrackFlac))
                {
                    PasteTag(_trackList.SelectedObjects[0], frm.DontPasteTitleField, frm.DontPasteTrackField, frm.DontPasteDiscField, frm.DontPasteBpmField,
                        frm.DontPasteLyricsField, frm.DontPasteArtistField);
                }

                _trackList.ListView.RefreshObjects((IList)_trackList.Objects);
            }
        }

        private void mnuDelete_Click(object sender, EventArgs e)
        {
            string message;

            int count = _trackList.SelectedObjects.Count;

            try
            {
                bool isSuccess = DeleteFiles(_trackList.SelectedObjects);

                RefreshTrackList(_currentPath);

                flvTagEditor.RefreshTree();

                if (isSuccess)
                {
                    message = string.Format("Successfully deleted {0} track(s)", count);

                    MessageBox.Show(this, message, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    message = "There was a problem when deleting the selected tracks";

                    MessageBox.Show(this, message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            catch (Exception ex)
            {
                message = string.Format("@There was a problem when moving or copying the selected track(s)\n\n{0}", ex.Message);

                MessageBox.Show(this, message, "@Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void mnuClose_Click(object sender, EventArgs e)
        {
            Close();
        }

        #endregion

        #region Edit Menu.

        private void mnuSelectAll_Click(object sender, EventArgs e)
        {
            SelectAll();
        }

        private void mnuSelectNone_Click(object sender, EventArgs e)
        {
            SelectNone();
        }

        private void mnuInvertSelection_Click(object sender, EventArgs e)
        {
            InvertSelection();
        }

        private void mnuSelectHighlightedFiles_Click(object sender, EventArgs e)
        {
            foreach (OLVListItem olvi in objectListView.SelectedItems)
            {
                if (olvi.Selected)
                {
                    olvi.Checked = true;
                }
            }
        }

        private void mnuUnselectHighlightedFiles_Click(object sender, EventArgs e)
        {
            foreach (OLVListItem olvi in objectListView.SelectedItems)
            {
                if (olvi.Selected)
                {
                    olvi.Checked = false;
                }
            }
        }

        private void mnuEditFileTag_Click(object sender, EventArgs e)
        {
            if (objectListView.SelectedObjects.Count > 0)
            {
                int index = objectListView.SelectedIndices[0];

                EditTag(index);
            }
        }

        private void mnuEditTagInSelectedFiles_Click(object sender, EventArgs e)
        {
            EditAllSupportedTags();
        }

        private void mnuEditFileName_Click(object sender, EventArgs e)
        {
            EditFileName();
        }

        private void mnuRenameFolder_Click(object sender, EventArgs e)
        {
            RenameFolder();
        }

        #endregion

        #region View Menu.

        private void mnuRefreshFileList_Click(object sender, EventArgs e)
        {
            RefreshTrackList(_currentPath);
        }

        private void mnuRefreshFolders_Click(object sender, EventArgs e)
        {
            flvTagEditor.RefreshTree();
        }

        private void mnuShowFolderCoverArt_Click(object sender, EventArgs e)
        {
            mnuShowFolderCoverArt.Checked = !mnuShowFolderCoverArt.Checked;
            pnxFolderCoverArt.Visible = mnuShowFolderCoverArt.Checked;
        }

        private void mnuShowFileCoverArt_Click(object sender, EventArgs e)
        {
            mnuShowFileCoverArt.Checked = !mnuShowFileCoverArt.Checked;
            pnxFileCoverArt.Visible = mnuShowFileCoverArt.Checked;
        }

        #endregion

        #region Tools Menu.

        private void mnuGetFolderJPGFromFilesTag_Click(object sender, EventArgs e)
        {
            const string message1 = "This will extract cover art from audio files tag to \"Folder.JPG\" into audio file folder \nIf the audio file folder already contains \"folder.jpg\", it will not be overwritten.";

            DialogResult result = MessageBox.Show(this, message1, "Confirmation", MessageBoxButtons.OKCancel,
                                                  MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);

            if (result == DialogResult.OK)
            {
                string folderImagePath = Path.Combine(_currentPath, "Folder.JPG");

                byte[] bytes;

                string message2;
                if (!File.Exists(folderImagePath) && TryGetFileCoverArtImage(out bytes))
                {
                    MemoryStream ms = null;
                    FileStream fs = null;

                    try
                    {
                        ms = new MemoryStream(bytes);

                        fs = new FileStream(folderImagePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);

                        ms.CopyTo(fs);

                        fs.Flush();

                        message2 = String.Format("Saved 1 folder cover art file\n\n [{0}]", folderImagePath);

                        MessageBox.Show(this, message2, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information,
                                        MessageBoxDefaultButton.Button1);
                    }
                    catch (Exception ex)
                    {
                        string message =
                            String.Format("There was a problem saving audio file art to the image file [{0}]\n\n{1}",
                                          folderImagePath, ex.Message);

                        MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    finally
                    {
                        if (fs != null) fs.Close();
                        if (ms != null) ms.Close();
                    }
                }
                else
                {
                    message2 = String.Format("Saved 0 folder cover art file");

                    MessageBox.Show(this, message2, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information,
                                    MessageBoxDefaultButton.Button1);
                }
            }
        }

        private void mnuAddFolderJPGToFilesTag_Click(object sender, EventArgs e)
        {
            const string message1 = "This function will add \"folder.jpg\" file from music folder into the audio file tag\nIf the audio file already contains cover art, it will not be overwritten.";

            DialogResult result = MessageBox.Show(this, message1, "Confirmation", MessageBoxButtons.OKCancel,
                                                  MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);

            if (result == DialogResult.OK)
            {
                AddFolderArtToAudioFileTag();
            }
        }

        private void mnuAutoFillTracks_Click(object sender, EventArgs e)
        {
            AutoFillTracks();
        }

        private void mnuFormatTrackToX_Click(object sender, EventArgs e)
        {
            FormatTrackTo_X();
        }

        private void mnuFormatTrackTo0x_Click(object sender, EventArgs e)
        {
            FormatTrackTo_0X();
        }

        private void mnuFormatTrackTo00x_Click(object sender, EventArgs e)
        {
            FormatTrackTo_00X();
        }

        private void mnuFormatTrackToXxxx_Click(object sender, EventArgs e)
        {
            FormatTrackTo_XX_XX();
        }

        private void mnuFormatTrackToXx_Click(object sender, EventArgs e)
        {
            FormatTrackTo_XX();
        }

        private void mnuDeleteTrackNumber_Click(object sender, EventArgs e)
        {
            DeleteTrackNumber();
        }

        private void mnuFillDisc_Click(object sender, EventArgs e)
        {
            FillDiscNumber();
        }

        private void mnuTitleFromFile_Click(object sender, EventArgs e)
        {
            GetTitleFromFile();
        }

        private void mnuSelectImageEditor_Click(object sender, EventArgs e)
        {
            var frm = new FormSelectImageEditor(_editors, _currentEditor);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                _currentEditor = frm.CurrentEditor;
            }
        }

        #endregion

        #region Playlist Menu.

        private void mnuSaveSelectedFilesToPlaylist_Click(object sender, EventArgs e)
        {
            SavePlayList(_trackList.CheckedObjects);
        }

        private void mnuQuickSaveSelectedFilesToPlaylist_Click(object sender, EventArgs e)
        {
            QuickSavePlayList(_trackList.CheckedObjects);
        }

        private void mnuSaveAllFilesToPlaylist_Click(object sender, EventArgs e)
        {
            SavePlayList(_trackList.Objects);
        }

        private void mnuQuickSavePlaylistAllFiles_Click(object sender, EventArgs e)
        {
            QuickSavePlayList(_trackList.Objects);
        }

        #endregion

        #region Help Menu.

        private void mnuAbout_Click(object sender, EventArgs e)
        {
            var frm = new FormAbout();

            frm.ShowDialog(this);
        }

        #endregion

        #endregion

        #region Events.

        private void cboArtist_Leave(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(cboArtist.Text) && string.IsNullOrEmpty(txtAlbumArtist.Text))
            {
                txtAlbumArtist.Text = cboArtist.Text;
            }
        }

        private void cboFileNameMask_TextChanged(object sender, EventArgs e)
        {
            txtPreviewRename.Text = string.Format("{0}{1}", ShowPreView(cboMaskRename.Text), _currentExtension);
        }

        private void cboTagsFromFileMask_TextChanged(object sender, EventArgs e)
        {
            txtPreviewTagsFromFile.Text = string.Format("{0}{1}", ShowPreView(cboMaskTagsFromFile.Text), _currentExtension);
        }

        private void txtAlbum_TextChanged(object sender, EventArgs e)
        {
            btnCopyAlbum.Enabled = !string.IsNullOrEmpty(txtAlbum.Text);
        }

        #endregion

        #region Button Events.

        private void pnxFolderArt_CloseClick(object sender, EventArgs e)
        {
            pnxFolderCoverArt.Visible = false;
            mnuShowFolderCoverArt.Checked = false;
        }

        private void pnxFileCoverArt_CloseClick(object sender, EventArgs e)
        {
            pnxFileCoverArt.Visible = false;
            mnuShowFileCoverArt.Checked = false;
        }

        private void btnSaveTags_Click(object sender, EventArgs e)
        {
            SaveTags();
        }

        private void btnRemoveTags_Click(object sender, EventArgs e)
        {
            RemoveTags();
        }

        private void btnCopyTag_Click(object sender, EventArgs e)
        {
            if (_trackList.SelectedObjects.Count > 0)
            {
                cboArtist.Text = _trackList.SelectedObjects[0].Artist;

                int indexReleaseType;
                Int32.TryParse(_trackList.SelectedObjects[0].ReleaseType, out indexReleaseType);
                cboReleaseType.SelectedIndex = indexReleaseType;

                txtAlbum.Text = _trackList.SelectedObjects[0].Album;

                txtYear.Text = _trackList.SelectedObjects[0].Year;


                if (cboGenre.Items.IndexOf(_trackList.SelectedObjects[0].Genre) >= 0)
                {
                    cboGenre.SelectedIndex = cboGenre.Items.IndexOf(_trackList.SelectedObjects[0].Genre);
                }
                else
                {
                    cboGenre.Text = _trackList.SelectedObjects[0].Genre;
                }

                txtCatalog.Text = _trackList.SelectedObjects[0].Catalog;

                txtComment.Text = _trackList.SelectedObjects[0].Comment;

                txtAlbumArtist.Text = _trackList.SelectedObjects[0].Albumartist;
            }
        }

        private void btnCreateAlbumText_Click(object sender, EventArgs e)
        {
            var frm = new FormAlbum(txtCatalog.Text);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                txtAlbum.Text = frm.AlbumText;

                if (!string.IsNullOrEmpty(frm.Catalog))
                {
                    txtCatalog.Text = frm.Catalog;
                }
            }
        }

        private void btnCopyAlbum_Click(object sender, EventArgs e)
        {
            if(!string.IsNullOrEmpty(txtAlbum.Text))
            {
                string albumName = txtAlbum.Text.Replace(":", "_");

                Clipboard.SetText(albumName);
            }
        }

        private void btnEditAll_Click(object sender, EventArgs e)
        {
            EditAllSupportedTags();
        }

        private void btnMaskEditorRename_Click(object sender, EventArgs e)
        {
            var frm = new FormMaskEditor(cboMaskRename.Text, _currentPath, RenameType.FILENAME, _currentExtension);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                cboMaskRename.Items.Clear();

                LoadFileRenameMaskCombo();

                int index = cboMaskRename.Items.IndexOf(frm.Mask);

                if (index >= 0)
                {
                    cboMaskRename.SelectedIndex = index;
                }
                else
                {
                    cboMaskRename.Text = frm.Mask;
                }
            }
        }

        private void btnPreviewRename_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(cboMaskRename.Text))
            {
                return;
            }

            IList<Track> tracks = _trackList.CheckedObjects;

            var masks = new MaskHelperCollection { Mask = cboMaskRename.Text };

            var frm = new FormPreviewFileName(tracks, masks, chkReplaceRename.Checked, ucCaseRename.GetCaseType(), _currentPath, _currentExtension);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                if (cboMaskRename.Items.IndexOf(frm.GetCurrentMask) >= 0)
                {
                    cboMaskRename.SelectedIndex = cboMaskRename.Items.IndexOf(frm.GetCurrentMask);
                }
                else
                {
                    cboMaskRename.Text = frm.GetCurrentMask;
                }

                if (!string.IsNullOrEmpty(frm.GetCurrentMask))
                    RenameCheckedFiles();
            }
        }

        private void btnRename_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(cboMaskRename.Text))
            {
                int progress = 0;
                int total = _trackList.CheckedObjects.Count;
                var masks = new MaskHelperCollection { Mask = cboMaskRename.Text };

                foreach (Track track in _trackList.CheckedObjects)
                {
                    var trackRename = new TrackRename(track.FileName, track.FilePath, track.FullPath, chkReplaceRename.Checked, ucCaseRename.GetCaseType());

                    track.RenameTrack(masks, trackRename);

                    sblProgress.Value = ++progress * 100 / total;
                }

                sblProgress.Value = 0;

                if (RenameCheckedFiles())
                {
                    //btnUndo.Enabled = true;
                }
            }
        }

        private void btnUndo_Click(object sender, EventArgs e)
        {
            if (UndoRename())
            {
                //btnUndo.Enabled = false;
            }
        }

        #endregion

        #region CheckBox Events.

        private void icbArtist_CheckedChange(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            cboArtist.Enabled = e.Checked;
        }

        private void icbAlbum_CheckedChange(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtAlbum.Enabled = e.Checked;
        }

        private void icbYear_CheckedChange(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtYear.Enabled = e.Checked;
        }

        private void icbGenre_CheckedChange(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            cboGenre.Enabled = e.Checked;
        }

        private void icbComment_CheckedChange(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtComment.Enabled = e.Checked;
        }

        private void icbCatalog_CheckedChange(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtCatalog.Enabled = e.Checked;
        }

        private void icbReleaseType_CheckedChange(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            cboReleaseType.Enabled = e.Checked;
        }

        private void icbAlbumArtist_CheckedChange(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtAlbumArtist.Enabled = e.Checked;
        }

        #endregion

        #region ObjectListView Events.

        private void objectListView_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            EnableEditControlsFromCheckedItems(_trackList.CheckedObjects.Count > 0);

            Image img;
            long size;

            if (TryGetFileCoverArtImage(out img, out size))
            {
                picFileCoverArt.Image = img;
                lblFileCoverArtInfo.Text = String.Format("Picture: {0} x {1}, {2}", picFileCoverArt.Image.Width,
                                                         picFileCoverArt.Image.Height,
                                                         Functions.GetFileArtSizeFromBytes(size));
            }
            else
            {
                picFileCoverArt.Image = null;
                lblFileCoverArtInfo.Text = "Picture:";
            }

            UpdateStatusbar(_trackList.Objects.Count, _trackList.CheckedObjects.Count,
                            CalculateTrackTime(_trackList.Objects), CalculateTrackTime(_trackList.CheckedObjects),
                            CalculateSelectedTrackSize(_trackList.CheckedObjects),
                            CalculateArt(_trackList.CheckedObjects));
        }

        private void objectListView_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            EnableControlsFromSelectedItems(_trackList.SelectedObjects.Count > 0);

            if (_trackList.SelectedObject != null)
            {
                if (_trackList.SelectedObject.HasFileCoverArt)
                {
                    picFileCoverArt.Image = _trackList.SelectedObject.ArtImage;
                    lblFileCoverArtInfo.Text = String.Format("Picture: {0} x {1}, {2}", picFileCoverArt.Image.Width,
                                                             picFileCoverArt.Image.Height,
                                                             Functions.GetFileArtSizeFromBytes(
                                                                 _trackList.SelectedObject.ArtSize));
                }
                else
                {
                    picFileCoverArt.Image = null;
                    lblFileCoverArtInfo.Text = "Picture:";
                }
            }
            else
            {
                picFileCoverArt.Image = null;
                lblFileCoverArtInfo.Text = "Picture:";
            }
        }

        private void objectListView_SelectionChanged(object sender, EventArgs e)
        {
            if (_trackList.SelectedObjects != null)
            {
                if (_trackList.SelectedObjects.Count > 1)
                {
                    Text = string.Format("GD Flac Tool - [{0}] *",
                                         Functions.ShortenName(_trackList.SelectedObjects[0].FullPath, 200));
                }
                else if (_trackList.SelectedObjects.Count == 1)
                {
                    Text = string.Format("GD Flac Tool - [{0}]",
                                         Functions.ShortenName(_trackList.SelectedObject.FullPath, 200));
                }
                else
                {
                    Text = string.Format("GD Flac Tool - [{0}]", Functions.ShortenName(_currentPath, 200));
                }
            }
        }

        private void objectListView_BeforeSorting(object sender, BeforeSortingEventArgs e)
        {
            if(e.ColumnToSort == null)
                return;

            if (e.ColumnToSort.Tag.ToString() == "Track Number")
            {
                objectListView.CustomSorter = delegate(OLVColumn column, SortOrder order)
                {
                    objectListView.ListViewItemSorter = new AlphaNumericComparer(column, order);
                };
            }
            else
            {
                objectListView.CustomSorter = null;
                
                objectListView.PrimarySortOrder = e.SortOrder;
                objectListView.PrimarySortColumn = e.ColumnToSort;
                
                objectListView.SecondarySortOrder = e.SortOrder;
                objectListView.SecondarySortColumn = e.SecondaryColumnToSort;
            }            
        }

        private void objectListView_AfterSorting(object sender, AfterSortingEventArgs e)
        {
            _cancelSorting = false;
        }

        private void objectListView_ItemsChanged(object sender, ItemsChangedEventArgs e)
        {
            EnableControlsFromItemsChange(_trackList.Objects.Count > 0);

            EnableControlsFromSelectedItems(_trackList.SelectedObjects.Count > 0);
        }

        private void objectListView_CellClick(object sender, CellClickEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                EditTag(e.RowIndex);
            }
        }

        #endregion

        #region ToolBar Button Events.

        private void tbbOpen_Click(object sender, EventArgs e)
        {
            OpenFolder();
        }

        private void tbbRefresh_Click(object sender, EventArgs e)
        {
            RefreshTrackList(_currentPath);
        }

        private void tbbEditFileName_Click(object sender, EventArgs e)
        {
            EditFileName();
        }

        private void tbbRenameFolder_Click(object sender, EventArgs e)
        {
            RenameFolder();
        }

        private void tbbEditSelectedTag_Click(object sender, EventArgs e)
        {
            if (objectListView.SelectedObjects.Count > 0)
            {
                int index = objectListView.SelectedIndices[0];

                EditTag(index);
            }
        }

        private void tbbEditCheckedTags_Click(object sender, EventArgs e)
        {
            EditAllSupportedTags();
        }

        private void tbbMoveUp_Click(object sender, EventArgs e)
        {
            MoveFileUp();
        }

        private void tbbMoveDown_Click(object sender, EventArgs e)
        {
            MoveFileDown();
        }

        private void tbbSelectAll_Click(object sender, EventArgs e)
        {
            SelectAll();
        }

        private void tbbSelectNone_Click(object sender, EventArgs e)
        {
            SelectNone();
        }

        private void tbbInvertSelection_Click(object sender, EventArgs e)
        {
            InvertSelection();
        }

        private void tbbAutoNumberTracks_Click(object sender, EventArgs e)
        {
            AutoFillTracks();
        }

        private void tddFormatTrackToX_Click(object sender, EventArgs e)
        {
            FormatTrackTo_X();
        }

        private void tddFormatTrackTo0X_Click(object sender, EventArgs e)
        {
            FormatTrackTo_0X();
        }

        private void tddFormatTrackTo00X_Click(object sender, EventArgs e)
        {
            FormatTrackTo_00X();
        }

        private void tddFormatTrackToXX_XX_Click(object sender, EventArgs e)
        {
            FormatTrackTo_XX_XX();
        }

        private void tddFormatTrackToXX_Click(object sender, EventArgs e)
        {
            FormatTrackTo_XX();
        }

        private void tddDeleteTrack_Click(object sender, EventArgs e)
        {
            DeleteTrackNumber();
        }

        private void tbbFillDiscNumber_Click(object sender, EventArgs e)
        {
            FillDiscNumber();
        }

        private void tbbTitleFromFile_Click(object sender, EventArgs e)
        {
            GetTitleFromFile();
        }

        private void tbbSaveSelectedFilesToPlaylist_Click(object sender, EventArgs e)
        {
            SavePlayList(_trackList.CheckedObjects);
        }

        private void tbbQuickSaveSelectedFilesToPlaylist_Click(object sender, EventArgs e)
        {
            QuickSavePlayList(_trackList.CheckedObjects);
        }

        private void tbbSaveAllFilesToPlaylist_Click(object sender, EventArgs e)
        {
            SavePlayList(_trackList.Objects);
        }

        private void tbbQuickSavePlaylistAllFiles_Click(object sender, EventArgs e)
        {
            QuickSavePlayList(_trackList.Objects);
        }

        #endregion

        #region Cover Art Events.

        private void llbAdd_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            openFileDialog.Title = "Add Flac Cover Art";
            openFileDialog.Filter = "JPG JPEG(*.jpeg,*.jpg,*.jif,*.jpe)|*.jpeg;*.jpg;*.jif;*.jpe";
            openFileDialog.FilterIndex = 1;
            openFileDialog.InitialDirectory = _currentPath;

            DialogResult open = openFileDialog.ShowDialog(this);

            if (open == DialogResult.OK)
            {
                AddCoverArt(openFileDialog.FileName);
            }
        }

        private void llbRemove_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            RemoveFileArt();
        }

        private void llbEditFolderArt_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            string folderImagePath = Path.Combine(_currentPath, "Folder.JPG");

            if (File.Exists(_currentEditor))
            {
                string program = _currentEditor;

                var info = new ProcessStartInfo
                {
                    FileName = program,
                    Arguments = File.Exists(folderImagePath) ? string.Format("\"{0}\"", folderImagePath) : string.Empty,
                    UseShellExecute = false,
                    ErrorDialog = false
                };

                Process.Start(info);
            }
        }

        #endregion

        #region Save And Delete Tag And Pictures Methods.

        private void AddFolderArtToAudioFileTag()
        {
            string folderImagePath = Path.Combine(_currentPath, "folder.jpg");

            if (File.Exists(folderImagePath))
            {
                _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

                int counter = 0;
                int progress = 0;
                int total = _trackList.CheckedObjects.Count;

                byte[] bytes = Functions.GetImageByteArray(folderImagePath);

                foreach (Track track in _trackList.CheckedObjects)
                {
                    if (!track.HasFileCoverArt)
                    {
                        track.SaveFrontCoverArt(bytes);

                        counter++;
                    }

                    sblProgress.Value = ++progress * 100 / total;
                }

                Image img;

                if (TryGetFileCoverArtImage(out img))
                {
                    picFileCoverArt.Image = img;
                    lblFileCoverArtInfo.Text = String.Format("Picture: {0} x {1}, {2}", picFileCoverArt.Image.Width,
                                                             picFileCoverArt.Image.Height,
                                                             Functions.GetFolderArtSizeFromFile(folderImagePath));
                }
                else
                {
                    picFileCoverArt.Image = null;
                    lblFolderCoverArtInfo.Text = "Picture:";
                }

                _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

                UpdateStatusbar(_trackList.Objects.Count, _trackList.CheckedObjects.Count,
                                CalculateTrackTime(_trackList.Objects), CalculateTrackTime(_trackList.CheckedObjects),
                                CalculateSelectedTrackSize(_trackList.CheckedObjects),
                                CalculateArt(_trackList.CheckedObjects));

                sblProgress.Value = 0;

                string message = String.Format("Cover art was added to {0} files from {1} processed files!", counter,
                                               _trackList.CheckedObjects.Count);

                MessageBox.Show(this, message, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information,
                                MessageBoxDefaultButton.Button1);
            }
        }

        private void AddCoverArt(string path)
        {
            Image img;
            int progress = 0;
            int total = _trackList.CheckedObjects.Count;

            byte[] bytes = Functions.GetImageByteArray(path);

            foreach (Track track in _trackList.CheckedObjects)
            {
                try
                {
                    track.SaveFrontCoverArt(bytes);
                }
                catch (SaveArtException ex)
                {
                    string message = String.Format("{0} \n\n {1}", ex.ExceptionText, ex.Message);

                    MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error,
                                    MessageBoxDefaultButton.Button1);
                }

                sblProgress.Value = ++progress * 100 / total;
            }

            if (TryGetFileCoverArtImage(out img))
            {
                picFileCoverArt.Image = img;
                lblFileCoverArtInfo.Text = String.Format("Picture: {0} x {1}, {2}", picFileCoverArt.Image.Width,
                                                         picFileCoverArt.Image.Height,
                                                         Functions.GetFolderArtSizeFromFile(openFileDialog.FileName));
            }
            else
            {
                picFileCoverArt.Image = null;
                lblFileCoverArtInfo.Text = "Picture:";
            }

            _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

            UpdateStatusbar(_trackList.Objects.Count, _trackList.CheckedObjects.Count,
                            CalculateTrackTime(_trackList.Objects), CalculateTrackTime(_trackList.CheckedObjects),
                            CalculateSelectedTrackSize(_trackList.CheckedObjects),
                            CalculateArt(_trackList.CheckedObjects));

            sblProgress.Value = 0;
        }

        private void RemoveFileArt()
        {
            int progress = 0;
            int total = _trackList.CheckedObjects.Count;

            foreach (Track track in _trackList.CheckedObjects)
            {
                track.RemoveFrontCoverArt();

                sblProgress.Value = ++progress * 100 / total;
            }

            picFileCoverArt.Image = null;

            lblFileCoverArtInfo.Text = "Picture:";

            _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

            UpdateStatusbar(_trackList.Objects.Count, _trackList.CheckedObjects.Count,
                            CalculateTrackTime(_trackList.Objects), CalculateTrackTime(_trackList.CheckedObjects),
                            CalculateSelectedTrackSize(_trackList.CheckedObjects),
                            CalculateArt(_trackList.CheckedObjects));

            sblProgress.Value = 0;
        }

        private void SaveTags()
        {
            int progress = 0;
            int total = _trackList.CheckedObjects.Count;

            foreach (Track track in _trackList.CheckedObjects)
            {
                if (icbArtist.Checked)
                {
                    track.IsArtistChanged = true;
                    track.Artist = cboArtist.Text;
                }

                if (icbAlbum.Checked)
                {
                    track.IsAlbumChanged = true;
                    track.Album = txtAlbum.Text;
                }

                if (icbYear.Checked)
                {
                    track.IsYearChanged = true;
                    track.Year = txtYear.Text;
                }

                if (icbGenre.Checked)
                {
                    track.IsGenreChanged = true;
                    track.Genre = cboGenre.Text;
                }

                if (icbComment.Checked)
                {
                    track.IsCommentChanged = true;
                    track.Comment = txtComment.Text;
                }

                if (icbCatalog.Checked)
                {
                    track.IsCatalogChanged = true;
                    track.Catalog = txtCatalog.Text;
                }

                if (icbReleaseType.Checked)
                {
                    track.IsReleaseTypeChanged = true;
                    track.ReleaseType = cboReleaseType.SelectedIndex.ToString(CultureInfo.InvariantCulture);
                }

                if (icbAlbumArtist.Checked)
                {
                    track.IsAlbumArtistChanged = true;
                    track.Albumartist = txtAlbumArtist.Text;
                }

                if (ucCaseMultiTag.CaseChecked)
                {
                    CaseFormatting(track, ucCaseMultiTag.GetCaseType());
                }

                track.SetTags();

                sblProgress.Value = ++progress * 100 / total;
            }

            _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

            sblProgress.Value = 0;
        }

        private void RemoveTags()
        {
            const string text = "Do you really want to remove tags from all selected files?";

            DialogResult dlg = MessageBox.Show(this, text, "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);

            if (dlg == DialogResult.Yes)
            {
                int progress = 0;
                int total = _trackList.CheckedObjects.Count;

                foreach (Track track in _trackList.CheckedObjects)
                {
                    track.Artist = string.Empty;
                    track.IsArtistChanged = true;

                    track.Album = string.Empty;
                    track.IsAlbumChanged = true;

                    track.Title = string.Empty;
                    track.IsTitleChanged = true;

                    track.Year = string.Empty;
                    track.IsYearChanged = true;

                    //track.ReleaseYear = string.Empty;
                    //track.IsReleaseYearChanged = true;

                    track.Genre = string.Empty;
                    track.IsGenreChanged = true;

                    track.Catalog = string.Empty;
                    track.IsCatalogChanged = true;

                    track.TrackNumber = string.Empty;
                    track.IsTrackNumberChanged = true;

                    track.DiscNumber = string.Empty;
                    track.IsDiscNumberChanged = true;

                    track.Comment = string.Empty;
                    track.IsCommentChanged = true;

                    track.ReleaseType = "0";
                    track.IsReleaseTypeChanged = true;

                    track.Albumartist = string.Empty;
                    track.IsAlbumArtistChanged = true;

                    track.SetTags();

                    sblProgress.Value = ++progress * 100 / total;
                }

                _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

                sblProgress.Value = 0;
            }
        }

        private void UpdateEditAllChanges(Image imgage, byte[] imageData)
        {
            int progress = 0;
            int total = _trackList.CheckedObjects.Count;

            foreach (Track track in _trackList.CheckedObjects)
            {
                track.SetTags();

                if (track.IsCoverArtChanged)
                {
                    if (imageData != null)
                    {
                        track.SaveFrontCoverArt(imageData);
                    }
                    else
                    {
                        track.RemoveFrontCoverArt();
                    }
                }

                sblProgress.Value = ++progress * 100 / total;
            }

            if (imgage != null && imageData != null)
            {
                picFileCoverArt.Image = imgage;
                lblFileCoverArtInfo.Text = String.Format("Picture: {0} x {1}, {2}", picFileCoverArt.Image.Width,
                                                         picFileCoverArt.Image.Height,
                                                         Functions.GetFileArtSizeFromBytes(imageData.Length));
            }
            else
            {
                picFileCoverArt.Image = null;
                lblFileCoverArtInfo.Text = "Picture:";
            }

            _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

            sblProgress.Value = 0;
        }

        #endregion

        #region Common ToolBar And Menu Methods.

        private void OpenFolder()
        {
            folderBrowserDialog.SelectedPath = flvTagEditor.SelectedNode.Path;

            DialogResult result = folderBrowserDialog.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                flvTagEditor.SelectNode(folderBrowserDialog.SelectedPath, true);
            }
        }

        private void EditFileName()
        {
            var frm = new FormEditFileName(objectListView);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                _trackList.ListView.RefreshObjects((IList)_trackList.Objects);
            }
        }

        private void RenameFolder()
        {
            if (_trackList.Objects.Count < 1)
            {
                return;
            }

            var frm = new FormRenameFolder(_trackList.Objects[0]);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                string oldPath = flvTagEditor.SelectedNode.Path;
                string[] directories = oldPath.Split(Path.DirectorySeparatorChar);

                string oldFolder = directories[directories.Length - 1];

                if (!string.IsNullOrEmpty(oldFolder))
                {
                    string newPath = oldPath.Remove(oldPath.Length - oldFolder.Length);

                    newPath = string.Format("{0}{1}", newPath, frm.FolderName);

                    try
                    {
                        var di = new DirectoryInfo(oldPath);

                        if (di.Exists == false)
                        {
                            di.Create();
                        }

                        if (Directory.Exists(newPath) == false)
                        {
                            di.MoveTo(newPath);

                            flvTagEditor.SelectNode(newPath, true);

                            flvTagEditor.RefreshTree();
                        }
                        else
                        {
                            string message = string.Format("There already exists a folder with that name:\n\n{0}", newPath);

                            MessageBox.Show(this, message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        }

                    }
                    catch (Exception ex)
                    {
                        string message = string.Format("There was a problem renaming the selected folder(s)\n\n{0}", ex.Message);

                        MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }

        private void EditAllSupportedTags()
        {
            Track selectedTracks = _trackList.SelectedObject;

            var frm = new FormMultiTagEditor(_trackList.CheckedObjects, selectedTracks,
                                                            _trackCollectiontracks.AllTracksHasFileImage, _currentPath,
                                                            _resetMultiTagEditor);

            _resetMultiTagEditor = false;

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                UpdateEditAllChanges(frm.GetImage, frm.GetImageByteArray);
            }
        }

        private void EditTag(int selectedIndex)
        {
            IList<Track> tracks = _trackList.Objects;

            int index = selectedIndex;

            if (index >= 0 && index < objectListView.Items.Count)
            {
                var frm = new FormSingleTagEditor(tracks, index, objectListView);

                DialogResult result = frm.ShowDialog(this);

                if (result == DialogResult.OK)
                {
                    _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

                    if (frm.Image != null)
                    {
                        picFileCoverArt.Image = frm.Image;
                        lblFileCoverArtInfo.Text = String.Format("Picture: {0} x {1}, {2}",
                                                                 picFileCoverArt.Image.Width,
                                                                 picFileCoverArt.Image.Height,
                                                                 Functions.GetFileArtSizeFromBytes(frm.ImageSize));
                    }
                    else
                    {
                        picFileCoverArt.Image = null;
                        lblFileCoverArtInfo.Text = "Picture:";
                    }
                }
            }
        }

        private void SelectAll()
        {
            _trackList.CheckedObjects = _trackList.Objects;
        }

        private void SelectNone()
        {
            _trackList.CheckedObjects = null;
        }

        private void InvertSelection()
        {
            foreach (OLVListItem olvi in _trackList.ListView.Items)
            {
                olvi.Checked = !olvi.Checked;
            }
        }

        private void AutoFillTracks()
        {
            var frm = new FormAutoNumber(_trackList.CheckedObjects);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                int progress = 0;
                int total = _trackList.CheckedObjects.Count;

                foreach (Track track in _trackList.CheckedObjects)
                {
                    track.SetTag(TagType.Tracknumber);

                    sblProgress.Value = ++progress * 100 / total;
                }

                _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

                sblProgress.Value = 0;
            }
        }

        private void FillDiscNumber()
        {
            var frm = new FormDiscNumber(_trackList.CheckedObjects);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                int progress = 0;
                int total = _trackList.CheckedObjects.Count;

                foreach (Track track in _trackList.CheckedObjects)
                {
                    track.SetTag(TagType.Discnumber);

                    sblProgress.Value = ++progress * 100 / total;
                }

                _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

                sblProgress.Value = 0;
            }
        }

        private void GetTitleFromFile()
        {
            var trackTitles = new TrackTitleCollection();
            trackTitles.AddRange(_trackList.CheckedObjects.Select(track => new TrackTitle(track.FileName, track.Title, track.TrackNumber)));

            var frm = new FormTitleEditor(_currentPath, trackTitles);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                if (frm.GetTitles.Count < 1)
                {
                    return;
                }

                int progress = 0;
                int total = _trackList.CheckedObjects.Count;

                TrackTitleCollection titles = frm.GetTitles;

                foreach (Track track in _trackList.CheckedObjects)
                {
                    track.Title = titles.FindTitleFromFileName(track.FileName);
                    track.TrackNumber = titles.FindTrackNumberFromFileName(track.FileName);

                    track.SetTag(TagType.Title, TagType.Tracknumber);

                    sblProgress.Value = ++progress * 100 / total;
                }

                _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

                sblProgress.Value = 0;
            }
        }

        private void FormatTrackTo_X()
        {
            foreach (Track t in _trackList.CheckedObjects)
            {
                int x;
                int progress = 0;
                int total = _trackList.CheckedObjects.Count;

                string[] trackNumber = SplitTrackNumber(t.TrackNumber);

                if (trackNumber.Length == 1)
                {
                    if (Int32.TryParse(trackNumber[0], out x))
                    {
                        t.TrackNumber = String.Format("{0}", x);
                    }
                }
                else
                {
                    if (Int32.TryParse(trackNumber[0], out x))
                    {
                        t.TrackNumber = String.Format("{0}/{1}", x, trackNumber[1]);
                    }
                }

                t.SetTag(TagType.Tracknumber);

                sblProgress.Value = ++progress * 100 / total;
            }

            _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

            sblProgress.Value = 0;
        }

        private void FormatTrackTo_0X()
        {
            foreach (Track t in _trackList.CheckedObjects)
            {
                int x;
                int progress = 0;
                int total = _trackList.CheckedObjects.Count;

                string[] trackNumber = SplitTrackNumber(t.TrackNumber);

                if (trackNumber.Length == 1)
                {
                    if (Int32.TryParse(trackNumber[0], out x))
                    {
                        t.TrackNumber = String.Format("{0:0#}", x);
                    }
                }
                else
                {
                    if (Int32.TryParse(trackNumber[0], out x))
                    {
                        t.TrackNumber = String.Format("{0:0#}/{1}", x, trackNumber[1]);
                    }
                }

                t.SetTag(TagType.Tracknumber);

                sblProgress.Value = ++progress * 100 / total;
            }

            _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

            sblProgress.Value = 0;
        }

        private void FormatTrackTo_00X()
        {
            foreach (Track t in _trackList.CheckedObjects)
            {
                int x;
                int progress = 0;
                int total = _trackList.CheckedObjects.Count;

                string[] trackNumber = SplitTrackNumber(t.TrackNumber);

                if (trackNumber.Length == 1)
                {
                    if (Int32.TryParse(trackNumber[0], out x))
                    {
                        t.TrackNumber = String.Format("{0:00#}", x);
                    }
                }
                else
                {
                    if (Int32.TryParse(trackNumber[0], out x))
                    {
                        t.TrackNumber = String.Format("{0:00#}/{1}", x, trackNumber[1]);
                    }
                }

                t.SetTag(TagType.Tracknumber);

                sblProgress.Value = ++progress * 100 / total;
            }

            _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

            sblProgress.Value = 0;
        }

        private void FormatTrackTo_XX_XX()
        {
            foreach (Track t in _trackList.CheckedObjects)
            {
                int progress = 0;
                int total = _trackList.CheckedObjects.Count;

                string[] trackNumber = SplitTrackNumber(t.TrackNumber);

                if (trackNumber.Length == 1)
                {
                    int x;
                    if (Int32.TryParse(trackNumber[0], out x))
                    {
                        t.TrackNumber = String.Format("{0:0#}/{1:0#}", x, _trackList.CheckedObjects.Count);
                    }
                }

                t.SetTag(TagType.Tracknumber);

                sblProgress.Value = ++progress * 100 / total;
            }

            _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

            sblProgress.Value = 0;
        }

        private void FormatTrackTo_XX()
        {
            foreach (Track t in _trackList.CheckedObjects)
            {
                int progress = 0;
                int total = _trackList.CheckedObjects.Count;

                string[] trackNumber = SplitTrackNumber(t.TrackNumber);

                if (trackNumber.Length == 2)
                {
                    int x;
                    if (Int32.TryParse(trackNumber[0], out x))
                    {
                        t.TrackNumber = String.Format("{0:0#}", x);
                    }
                }

                t.SetTag(TagType.Tracknumber);

                sblProgress.Value = ++progress * 100 / total;
            }

            _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

            sblProgress.Value = 0;
        }

        private void DeleteTrackNumber()
        {
            int progress = 0;
            int total = _trackList.CheckedObjects.Count;

            foreach (Track t in _trackList.CheckedObjects)
            {
                t.TrackNumber = String.Empty;

                t.SetTag(TagType.Tracknumber);

                sblProgress.Value = ++progress * 100 / total;
            }

            _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

            sblProgress.Value = 0;
        }

        #endregion

        #region Move File Up And Down.

        private void MoveFileUp()
        {
            IList<Track> checkedObject = _trackList.CheckedObjects;

            if (!_cancelSorting)
            {
                objectListView.Unsort();
                _cancelSorting = true;
                objectListView.PrimarySortColumn = null;
                objectListView.PrimarySortOrder = SortOrder.None;
            }

            if (_trackList.SelectedObjects.Count > 0)
            {
                if (_trackList.ListView.SelectedItems[0].Index == 0)
                {
                    return;
                }

                _trackList.ListView.BeginUpdate();

                foreach (ListViewItem listViewItem in _trackList.ListView.SelectedItems)
                {
                    int tmp = listViewItem.Index;

                    _trackList.ListView.Items.Remove(listViewItem);

                    _trackList.ListView.Items.Insert(tmp - 1, listViewItem);
                }

                _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

                RepaintObjectListView();

                _trackList.CheckedObjects = checkedObject;

                _trackList.ListView.EndUpdate();
            }
        }

        private void MoveFileDown()
        {
            IList<Track> checkedObject = _trackList.CheckedObjects;

            if (!_cancelSorting)
            {
                _trackList.ListView.Unsort();
                _cancelSorting = true;
                objectListView.PrimarySortColumn = null;
                objectListView.PrimarySortOrder = SortOrder.None;
            }

            if (_trackList.SelectedObjects.Count > 0)
            {
                if (_trackList.ListView.SelectedItems[_trackList.SelectedObjects.Count - 1].Index ==
                    _trackList.Objects.Count - 1)
                {
                    return;
                }

                _trackList.ListView.BeginUpdate();

                foreach (ListViewItem listViewItem in _trackList.ListView.SelectedItems)
                {
                    int tmp = listViewItem.Index;
                    int selected = _trackList.SelectedObjects.Count;

                    _trackList.ListView.Items.Remove(listViewItem);

                    _trackList.ListView.Items.Insert(tmp + selected, listViewItem);
                }

                _trackList.ListView.RefreshObject((IList)_trackList.Objects);

                RepaintObjectListView();

                _trackList.CheckedObjects = checkedObject;

                _trackList.ListView.EndUpdate();
            }
        }

        #endregion

        #region Load Track List.

        private void RefreshTrackList(string path)
        {
            bool isAllChecked = false;
            IList<Track> checkedObjects = null;

            if (!Directory.Exists(path))
            {
                picFolderCoverArt.Image = null;
                lblFolderCoverArtInfo.Text = "Picture:";
                picFileCoverArt.Image = null;
                lblFileCoverArtInfo.Text = "Picture:";
                llbEditFolderArt.Enabled = false;
                objectListView.SetObjects(null);

                try
                {
                    flvTagEditor.RefreshTree();
                }
                catch (NullReferenceException)
                {
                    //Do nothing;
                }
                
            }

            if (_trackList.CheckedObjects.Count > 0)
            {
                if (_trackList.CheckedObjects.Count == _trackList.ListView.Items.Count)
                {
                    isAllChecked = true;
                }
                else
                {
                    checkedObjects = _trackList.CheckedObjects;
                }
            }

            bool hasValidAudioFiles = ViewSelection(path);

            if (hasValidAudioFiles)
            {
                MruMenu.AddFile(path);

                string folderImagePath = Path.Combine(_currentPath, "Folder.JPG");

                ShowFolderCoverArtImage(folderImagePath);

                if (isAllChecked)
                {
                    _trackList.CheckedObjects = _trackList.Objects;
                }
                else
                {
                    if (checkedObjects != null)
                    {
                        foreach (Track track in _trackList.Objects)
                        {
                            foreach (Track check in checkedObjects)
                            {
                                if (track.FullPath == check.FullPath)
                                {
                                    objectListView.CheckObject(track);
                                }
                            }
                        }
                        objectListView.CheckObjects(checkedObjects);

                    }
                }

                if (!_cancelSorting)
                {
                    objectListView.Sort(objectListView.LastSortColumn, objectListView.LastSortOrder);
                }
            }
            else
            {
                picFolderCoverArt.Image = null;
                lblFolderCoverArtInfo.Text = "Picture:";
                picFileCoverArt.Image = null;
                lblFileCoverArtInfo.Text = "Picture:";
                llbEditFolderArt.Enabled = false;
            }
        }

        private bool ViewSelection(string path)
        {
            var paths = new List<string>();
            
            string[] flac = GetAllFilePaths(path, "*.flac");
            
            if(flac != null && flac.Length > 0)
                paths.AddRange(flac);

            string[] shn = GetAllFilePaths(path, "*.shn");

            if (shn != null && shn.Length > 0)
                paths.AddRange(shn);

            if (paths.Count > 0)
            {
                MainSettings.Default.FolderViewStartFolder = path;

                FillTrackList(paths);

                return true;
            }

            objectListView.SetObjects(null);
            return false;
        }

        private string[] GetAllFilePaths(string path, string extension)
        {
            if (!Directory.Exists(path))
                return null;

            string[] filePaths = Directory.GetFiles(path, extension);

            return filePaths;
        }

        private void FillTrackList(List<string> paths)
        {
            _trackCollectiontracks.Clear();

            int progress = 0;
            int total = paths.Count;

            foreach (string path in paths)
            {
                if (File.Exists(path))
                {
                    Track track = null;

                    if(Path.GetExtension(path) == ".flac")
                    {
                        track = new TrackFlac(path);
                    }
                    else if(Path.GetExtension(path) == ".shn")
                    {
                        track = new TrackShn(path);
                    }

                    if (track != null && !track.IsEmpty)
                    {
                        _trackCollectiontracks.Add(track);
                    }
                    else
                    {
                        string message = string.Format("The file: {0} is corrupt or not a valid file", path);

                        MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }

                sblProgress.Value = ++progress * 100 / total;
            }

            olvColumnReleaseType.AspectToStringConverter = delegate(object x)
            {
                int index;
                if (Int32.TryParse(x.ToString(), out index))
                {
                    return String.Format("{0}",Functions.TranslateReleaseType(index));
                }

                return String.Empty;
            };

            olvColumnSize.AspectToStringConverter = delegate(object x)
            {
                var size = (long)x;
                var limits = new[] { 1024 * 1024 * 1024, 1024 * 1024, 1024 };
                var units = new[] { "GB", "MB", "KB" };

                for (int i = 0; i < limits.Length; i++)
                {
                    if (size >= limits[i])return String.Format("{0:#,##0.0} " + units[i], ((double)size / limits[i]));
                }

                return String.Format("{0} bytes", size);
            };

            olvColumnCoverArt.AspectGetter = x => ((Track)x).HasFileCoverArt;

            olvColumnCoverArt.AspectToStringConverter = value => String.Empty;

            olvColumnCoverArt.ImageGetter = delegate(object x)
            {
                if (((Track)x).HasFileCoverArt)
                    return "HasCoverArt";
                return "NoCoverArt";
            };

            //objectListView.CustomSorter = delegate(OLVColumn column, SortOrder order)
            //{
            //    if (column.Tag.ToString() == "Track Number")
            //        objectListView.ListViewItemSorter = new AlphaNumericComparer(column, order);
            //    else
            //    {
            //        objectListView.CustomSorter = null;
            //    }
            //};

            olvColumnRating.Renderer = new MultiImageRenderer(Resources.Star1, 5, 0, 6);

            olvColumnFilename.ImageGetter = x => ((Track) x).TrackFormat;

            olvColumnIsSupported.AspectGetter = x => ((Track)x).HasFileCoverArt;

            olvColumnIsSupported.AspectToStringConverter = value => String.Empty;

            olvColumnIsSupported.ImageGetter = delegate(object x)
            {
                if (((Track)x).IsSupportedTag)
                {
                    return "Supported";
                }
                    
                return "Unsupported";
            };
            
            objectListView.SetObjects(_trackCollectiontracks, true);

            if (_trackList.Objects.Count > 0)
            {
                _currentExtension = Path.GetExtension(_trackList.Objects[0].FileName);
            }
            else
            {
                _currentExtension = string.Empty;
            }

            sblProgress.Value = 0;
        }

        #endregion

        #region Private Methods.

        private bool TryGetFileCoverArtImage(out byte[] bytes)
        {
            bytes = null;

            foreach (Track track in _trackList.CheckedObjects)
            {
                if (track.HasFileCoverArt)
                {
                    bytes = track.ArtByteArray;

                    return true;
                }
            }

            return false;
        }

        private bool TryGetFileCoverArtImage(out Image img)
        {
            img = null;

            foreach (Track track in _trackList.CheckedObjects)
            {
                if (track.HasFileCoverArt)
                {
                    img = track.ArtImage;

                    return true;
                }
            }

            return false;
        }

        private bool TryGetFileCoverArtImage(out Image img, out long size)
        {
            img = null;
            size = 0;

            foreach (Track track in _trackList.CheckedObjects)
            {
                if (track.HasFileCoverArt)
                {
                    img = track.ArtImage;
                    size = track.ArtSize;

                    return true;
                }
            }

            return false;
        }

        private void RepaintObjectListView()
        {
            foreach (OLVListItem item in objectListView.Items)
            {
                item.BackColor = item.Index % 2 != 1 ? Color.FromArgb(204, 255, 255) : Color.FromArgb(255, 255, 255);
            }
        }

        private void CaseFormatting(Track track, CaseType type)
        {
            TextInfo myTI = new CultureInfo("en-US", false).TextInfo;

            if (type == CaseType.Lower)
            {
                track.Artist = myTI.ToLower(track.Artist);
                track.Album = myTI.ToLower(track.Album);
                track.Title = myTI.ToLower(track.Title);
                track.Genre = myTI.ToLower(track.Genre);
                track.Albumartist = myTI.ToLower(track.Albumartist);

                track.IsArtistChanged = true;
                track.IsAlbumChanged = true;
                track.IsTitleChanged = true;
                track.IsGenreChanged = true;
                track.IsAlbumArtistChanged = true;
            }

            if (type == CaseType.Upper)
            {
                track.Artist = myTI.ToUpper(track.Artist);
                track.Album = myTI.ToUpper(track.Album);
                track.Title = myTI.ToUpper(track.Title);
                track.Genre = myTI.ToUpper(track.Genre);
                track.Albumartist = myTI.ToUpper(track.Albumartist);

                track.IsArtistChanged = true;
                track.IsAlbumChanged = true;
                track.IsTitleChanged = true;
                track.IsGenreChanged = true;
                track.IsAlbumArtistChanged = true;
            }

            if (type == CaseType.FirstLetter)
            {
                track.Artist = myTI.ToTitleCase(track.Artist.ToLower());
                track.Album = myTI.ToTitleCase(track.Album.ToLower());
                track.Title = myTI.ToTitleCase(track.Title.ToLower());
                track.Genre = myTI.ToTitleCase(track.Genre.ToLower());
                track.Albumartist = myTI.ToTitleCase(track.Albumartist.ToLower());

                track.IsArtistChanged = true;
                track.IsAlbumChanged = true;
                track.IsTitleChanged = true;
                track.IsGenreChanged = true;
                track.IsAlbumArtistChanged = true;
            }

            if (type == CaseType.FirstWord)
            {
                track.Artist = track.Artist.ToLower().ToUpperFirstLetter();
                track.Album = track.Album.ToLower().ToUpperFirstLetter();
                track.Title = track.Title.ToLower().ToUpperFirstLetter();
                track.Genre = track.Genre.ToLower().ToUpperFirstLetter();
                track.Albumartist = track.Albumartist.ToLower().ToUpperFirstLetter();

                track.IsArtistChanged = true;
                track.IsAlbumChanged = true;
                track.IsTitleChanged = true;
                track.IsGenreChanged = true;
                track.IsAlbumArtistChanged = true;
            }
        }

        private string[] SplitTrackNumber(string track)
        {
            if (!String.IsNullOrEmpty(track))
            {
                string[] split = track.Split('/');

                return split;
            }

            return new[] { String.Empty };
        }

        private void EnableControlsFromSelectedItems(bool enable)
        {
            tbbMoveUp.Enabled = enable;
            tbbMoveDown.Enabled = enable;
            tbbEditSelectedTag.Enabled = enable;

            mnuMoveFileUp.Enabled = enable;
            mnuMoveFileDown.Enabled = enable;
            mnuDelete.Enabled = enable;
            mnuEditFileTag.Enabled = enable;
            mnuCopyTag.Enabled = enable;
            mnuPasteTag.Enabled = enable;

            mnuPasteTag.Enabled = CheckClipboard();

            btnCopyTag.Enabled = enable;
        }

        private void EnableControlsFromItemsChange(bool enabled)
        {
            tbbSelectAll.Enabled = enabled;
            tbbSelectNone.Enabled = enabled;
            tbbInvertSelection.Enabled = enabled;
            tbbEditFileName.Enabled = enabled;
            tbbRenameFolder.Enabled = enabled;
            tbbSaveAllFilesToPlaylist.Enabled = enabled;
            tbbQuickSavePlaylistAllFiles.Enabled = enabled;

            mnuSelectAll.Enabled = enabled;
            mnuSelectNone.Enabled = enabled;
            mnuInvertSelection.Enabled = enabled;
            mnuSelectHighlightedFiles.Enabled = enabled;
            mnuUnselectHighlightedFiles.Enabled = enabled;
            mnuEditFileName.Enabled = enabled;
            mnuRenameFolder.Enabled = enabled;
            mnuSaveAllFilesToPlaylist.Enabled = enabled;
            mnuQuickSavePlaylistAllFiles.Enabled = enabled;
        }

        private void EnableEditControlsFromCheckedItems(bool enabled)
        {
            btnSaveTags.Enabled = enabled;
            btnRemoveTags.Enabled = enabled;
            btnEditAll.Enabled = enabled;
            btnPreviewRename.Enabled = enabled;
            btnRename.Enabled = enabled;
            btnPreviewTagFromFile.Enabled = enabled;
            btnWriteTags.Enabled = enabled;
            
            mnuSaveTags.Enabled = enabled;
            mnuRemoveTags.Enabled = enabled;
            mnuFormatTrackToX.Enabled = enabled;
            mnuFormatTrackTo0x.Enabled = enabled;
            mnuFormatTrackTo00x.Enabled = enabled;
            mnuFormatTrackToXxxx.Enabled = enabled;
            mnuFormatTrackToXx.Enabled = enabled;
            mnuAutoFillTracks.Enabled = enabled;
            mnuDeleteTrackNumber.Enabled = enabled;
            mnuFillDisc.Enabled = enabled;
            mnuTitleFromFile.Enabled = enabled;
            mnuAddFolderJPGToFilesTag.Enabled = enabled;
            mnuGetFolderJPGFromFilesTag.Enabled = enabled;
            mnuCheckMD5.Enabled = enabled;
            mnuCreateMD5Sum.Enabled = enabled;
            mnuViewReport.Enabled = enabled;
            mnuEditTagInSelectedFiles.Enabled = enabled;
            mnuSaveSelectedFilesToPlaylist.Enabled = enabled;
            mnuQuickSaveSelectedFilesToPlaylist.Enabled = enabled;

            tbbAutoNumberTracks.Enabled = enabled;
            tdbFormatTrack.Enabled = enabled;
            tbbFillDiscNumber.Enabled = enabled;
            tbbTitleFromFile.Enabled = enabled;
            tbbEditCheckedTags.Enabled = enabled;
            tbbSaveSelectedFilesToPlaylist.Enabled = enabled;
            tbbQuickSaveSelectedFilesToPlaylist.Enabled = enabled;

            llbAdd.Enabled = enabled;
            llbRemove.Enabled = enabled;
        }

        private void LoadArtistCombo()
        {
            StringCollection artists = MainSettings.Default.Artists;

            foreach (string artist in artists)
            {
                cboArtist.Items.Add(artist);
            }
        }

        private void LoadGenreCombo()
        {
            string[] genres = Genres.Audio;

            for (int i = 0; i < Genres.Audio.Length; i++)
            {
                cboGenre.Items.Add(genres[i]);
            }
        }

        private void LoadFileRenameMaskCombo()
        {
            StringCollection masksRename = MaskEditorSettings.Default.SavedRenameMasks;

            if (masksRename != null)
            {
                foreach (var mask in masksRename)
                {
                    cboMaskRename.Items.Add(mask);
                }
            }
        }

        private void LoadTagFromFileMaskCombo()
        {
            StringCollection masksTagsFromFile = MaskEditorSettings.Default.SavedTagsFromFileMasks;

            if (masksTagsFromFile != null)
            {
                foreach (var mask in masksTagsFromFile)
                {
                    cboMaskTagsFromFile.Items.Add(mask);
                }
            }
        }

        private void ShowFolderCoverArtImage(string path)
        {
            if (File.Exists(path))
            {
                FileStream fs = null;

                try
                {
                    fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);

                    Image image = Image.FromStream(fs);

                    lblFolderCoverArtInfo.Text = String.Format("Picture: {0} x {1}, {2}", image.Width, image.Height,
                                                               Functions.GetFolderArtSizeFromFile(path));

                    picFolderCoverArt.Image = image;

                    llbEditFolderArt.Enabled = true;
                }
                catch (Exception ex)
                {
                    string message = String.Format("There was a problem viewing the folder picture file [{0}]\n\n{1}",
                                                   path, ex.Message);

                    MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    if (fs != null) fs.Close();
                }
            }
            else
            {
                picFolderCoverArt.Image = null;
                lblFolderCoverArtInfo.Text = "Picture:";
                llbEditFolderArt.Enabled = false;
            }
        }

        private void UpdateStatusbar(int totalFiles, int selectedFiles, string totalTime, string selectedTime,
                                     string selectedSize, int coverArt)
        {
            const string totFiles = "Total files:";
            const string selFiles = "Selected files:";
            const string totTime = "Total time:";
            const string selTime = "Selected time:";
            const string art = "Cover art in:";

            sblTotalFiles.Text = String.Format("{0} {1}", totFiles, totalFiles);
            sblSelectedFiles.Text = String.Format("{0} {1}", selFiles, selectedFiles);
            sblTotalTime.Text = String.Format("{0} {1}", totTime, totalTime);
            sblSelectedTime.Text = String.Format("{0} {1}", selTime, selectedTime);
            sblSelectedFileSize.Text = String.Format("{0}", selectedSize);
            sblFolderArt.Text = string.Format("{0} {1} of {2} selected file(s)", art, coverArt, selectedFiles);
        }

        private int CalculateArt(IEnumerable<Track> tracks)
        {
            return tracks.Count(track => track.HasFileCoverArt);
        }

        private string CalculateTrackTime(IList<Track> tracks)
        {
            if (tracks.Count < 1)
            {
                return "00:00:00";
            }

            long sumTime = tracks.Sum(track => track.TimeTicks);

            if (sumTime == 0)
                return "00:00:00";

            var timeSpan = new TimeSpan(sumTime);

            return String.Format("{0:0#}:{1:0#}:{2:0#}", timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds);
        }

        private string CalculateSelectedTrackSize(IList<Track> tracks)
        {
            if (tracks.Count < 1)
            {
                return String.Empty;
            }

            var limits = new[] { 1024 * 1024 * 1024, 1024 * 1024, 1024 };
            var units = new[] { "GB", "MB", "KB" };

            long size = tracks.Sum(track => track.Size);

            for (int i = 0; i < limits.Length; i++)
            {
                if (size >= limits[i])
                    return String.Format("{0:#,##0.0} " + units[i], ((double)size / limits[i]));
            }

            return String.Format("{0} bytes", size);
        }

        #endregion

        #region MD5 Functions.

        private void mnuCheckMD5_Click(object sender, EventArgs e)
        {
            string[] md5FilePaths = GetAllFilePaths(_currentPath, "*.md5");
            string selectedMd5File;

            if (md5FilePaths == null || md5FilePaths.Length < 1)
            {
                const string message = "Could not find any .md5 file to verify current .flac files against";

                MessageBox.Show(this, message, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);

                return;
            }

            if (md5FilePaths.Length > 1)
            {
                var frm1 = new FormSelectMd5File(md5FilePaths);

                DialogResult result1 = frm1.ShowDialog(this);

                if (result1 == DialogResult.OK)
                {
                    selectedMd5File = frm1.SelectedMd5File;
                }
                else
                {
                    return;
                }
            }
            else
            {
                selectedMd5File = md5FilePaths[0];
            }

            var frm2 = new FormCheckMd5(selectedMd5File);

            frm2.ShowDialog(this);
        }

        private void mnuCreateMD5Sum_Click(object sender, EventArgs e)
        {
            TrackMd5Collection collection = CreateMd5Collection();

            var frm = new FormCreateMd5(collection, _currentPath);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {

            }
        }

        private TrackMd5Collection CreateMd5Collection()
        {
            var collection = new TrackMd5Collection();

            foreach (Track track in _trackList.CheckedObjects)
            {
                var md5 = new TrackMd5
                {
                    Filename = track.FileName,
                    Filepath = track.FullPath,
                    Status = KeyStatus.Unprocessed,
                    Filesize = Functions.GetFileArtSizeFromBytes(track.Size)
                };


                collection.Add(md5);
            }

            return collection;
        }

        #endregion

        #region Rename Functions.

        private bool UndoRename()
        {
            int progress = 0;
            int total = _trackList.CheckedObjects.Count;

            foreach (Track track in _trackList.CheckedObjects)
            {
                if (track.IsTrackRenamed)
                {
                    try
                    {
                        if (!Directory.Exists(track.Trackrename.OriginalPath))
                        {
                            var directoryInfo = new DirectoryInfo(track.Trackrename.OriginalPath);

                            directoryInfo.Create();
                        }

                        File.Move(track.FullPath, track.Trackrename.OriginalFullPath);

                        track.FileName = track.Trackrename.OriginalFileName;
                        track.FilePath = track.Trackrename.OriginalPath;
                        track.FullPath = track.Trackrename.OriginalFullPath;
                    }
                    catch (IOException ex)
                    {
                        string message = string.Format("There was a problem performing undo on:\n\n{0}\n\nback to\n\n{1}\n\n{2}",
                                                       track.Trackrename.RenamedFileName, track.FileName, ex.Message);

                        MessageBox.Show(this, message, "Varning", MessageBoxButtons.OK, MessageBoxIcon.Warning);

                        return false;
                    }

                    track.ClearUndo();
                }

                sblProgress.Value = ++progress * 100 / total;
            }

            //RefreshTrackList(_currentPath);

            _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

            flvTagEditor.RefreshTree();

            sblProgress.Value = 0;

            btnUndo.Enabled = false;

            return true;
        }

        private bool RenameCheckedFiles()
        {
            int progress = 0;
            int total = _trackList.CheckedObjects.Count;

            foreach (Track track in _trackList.CheckedObjects)
            {
                if (track.IsTrackRenamed)
                {
                    try
                    {
                        if (!Directory.Exists(track.Trackrename.RenamedPath))
                        {
                            var directoryInfo = new DirectoryInfo(track.Trackrename.RenamedPath);

                            directoryInfo.Create();
                        }

                        File.Move(track.FullPath, track.Trackrename.RenamedFullPath);

                        track.FileName = track.Trackrename.RenamedFileName;
                        track.FilePath = track.Trackrename.RenamedPath;
                        track.FullPath = track.Trackrename.RenamedFullPath;

                        track.UpdateAfterRename();
                    }
                    catch (IOException ex)
                    {
                        string message = string.Format("There was a problem to rename:\n\n{0}\n\nto\n\n{1}\n\n{2}",
                                                       track.FileName, track.Trackrename.RenamedFileName, ex.Message);

                        MessageBox.Show(this, message, "Varning", MessageBoxButtons.OK, MessageBoxIcon.Warning);

                        return false;
                    }
                }

                sblProgress.Value = ++progress * 100 / total;
            }

            //RefreshTrackList(_currentPath);

            _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

            flvTagEditor.RefreshTree();

            sblProgress.Value = 0;

            btnUndo.Enabled = true;

            return true;
        }

        private string ShowPreView(string mask)
        {
            if (string.IsNullOrEmpty(mask))
                return string.Empty;

            string result = mask;

            var helper = new MaskHelperCollection();

            return helper.Aggregate(result, (current, maskHelper) => current.Replace(maskHelper.Mask, maskHelper.Example));
        }

        #endregion

        #region Tags From File Name.

        private void btnMaskEditorTagsFromFile_Click(object sender, EventArgs e)
        {
            var frm = new FormMaskEditor(cboMaskTagsFromFile.Text, _currentPath, RenameType.TAGFROMFILE, _currentExtension);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                cboMaskTagsFromFile.Items.Clear();

                LoadTagFromFileMaskCombo();

                int index = cboMaskTagsFromFile.Items.IndexOf(frm.Mask);

                if (index >= 0)
                {
                    cboMaskTagsFromFile.SelectedIndex = index;
                }
                else
                {
                    cboMaskTagsFromFile.Text = frm.Mask;
                }
            }
        }

        private void btnPreviewTagFromFile_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(cboMaskTagsFromFile.Text))
            {
                return;
            }

            IList<Track> checkedTracks = _trackList.CheckedObjects;

            var masks = new MaskHelperCollection { Mask = cboMaskTagsFromFile.Text };

            var frm = new FormPreviewTagFromFile(checkedTracks, masks, chkReplaceTagsFromFile.Checked, ucCaseTagsFromFile.CaseChecked, ucCaseTagsFromFile.GetCaseType(), _currentPath, _currentExtension);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                IList<TagFileObject> tagFileObjects = frm.GetTagFileObjects;

                if (frm.CountTagChanges > 0)
                {
                    RenameTracksFromFileName(checkedTracks, tagFileObjects);
                }

                if (cboMaskTagsFromFile.Items.IndexOf(frm.GetCurrentMask) >= 0)
                {
                    cboMaskTagsFromFile.SelectedIndex = cboMaskTagsFromFile.Items.IndexOf(frm.GetCurrentMask);
                }
                else
                {
                    cboMaskTagsFromFile.Text = frm.GetCurrentMask;
                }
            }
        }

        private void btnWriteTags_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(cboMaskTagsFromFile.Text))
            {
                return;
            }

            IList<Track> checkedTracks = _trackList.CheckedObjects;

            var masks = new MaskHelperCollection { Mask = cboMaskTagsFromFile.Text };

            var _helper = new TagFromFileHelper(masks.Mask, chkReplaceTagsFromFile.Checked, ucCaseTagsFromFile.CaseChecked, ucCaseTagsFromFile.GetCaseType());

            List<TagFileObject> objects = _helper.GetTagFromFilename(checkedTracks, _helper.GetTagHelper);

            RenameTracksFromFileName(checkedTracks, objects);
        }

        private void RenameTracksFromFileName(IList<Track> tracks, IList<TagFileObject> tagFileObjects)
        {
            int progress = 0;
            int total = tracks.Count;

            foreach (var track in tracks)
            {
                foreach (var tagFileObject in tagFileObjects)
                {
                    if (track.FileName == tagFileObject.FileName)
                    {
                        if (!string.IsNullOrEmpty(tagFileObject.Artist))
                        {
                            track.Artist = tagFileObject.Artist;
                            track.IsArtistChanged = true;
                        }

                        if (!string.IsNullOrEmpty(tagFileObject.Title))
                        {
                            track.Title = tagFileObject.Title;
                            track.IsTitleChanged = true;
                        }

                        if (!string.IsNullOrEmpty(tagFileObject.Album))
                        {
                            track.Album = tagFileObject.Album;
                            track.IsAlbumChanged = true;
                        }

                        if (!string.IsNullOrEmpty(tagFileObject.Year))
                        {
                            track.Year = tagFileObject.Year;
                            track.IsYearChanged = true;
                        }

                        if (!string.IsNullOrEmpty(tagFileObject.Genre))
                        {
                            track.Genre = tagFileObject.Genre;
                            track.IsGenreChanged = true;
                        }

                        if (!string.IsNullOrEmpty(tagFileObject.Track))
                        {
                            track.TrackNumber = tagFileObject.Track;
                            track.IsTrackNumberChanged = true;
                        }

                        if (!string.IsNullOrEmpty(tagFileObject.Disc))
                        {
                            track.DiscNumber = tagFileObject.Disc;
                            track.IsDiscNumberChanged = true;
                        }

                        if (!string.IsNullOrEmpty(tagFileObject.Comment))
                        {
                            track.Comment = tagFileObject.Comment;
                            track.IsCommentChanged = true;
                        }

                        if (!string.IsNullOrEmpty(tagFileObject.AlbumArtist))
                        {
                            track.Albumartist = tagFileObject.AlbumArtist;
                            track.IsAlbumArtistChanged = true;
                        }

                        if (!string.IsNullOrEmpty(tagFileObject.Catalog))
                        {
                            track.Catalog = tagFileObject.Catalog;
                            track.IsCatalogChanged = true;
                        }
                    }
                }

                track.SetTags();

                sblProgress.Value = ++progress * 100 / total;
            }

            _trackList.ListView.RefreshObjects((IList)_trackList.Objects);

            sblProgress.Value = 0;
        }

        #endregion

        #region Drag And Drop Operations.

        private void flvTagEditor_FolderViewDragOver(object sender, FolderViewDragOverEventArgs e)
        {
            bool isDataOk = e.Data.GetDataPresent(typeof(TrackDragObject));

            if ((e.KeyState & 4) == 4 && isDataOk)
            {
                e.Effects = DragDropEffects.Move;
                _dragDropEffects = e.Effects;
            }
            else if ((e.KeyState & 8) == 8 && isDataOk)
            {
                e.Effects = DragDropEffects.Copy;
                _dragDropEffects = e.Effects;
            }
            else if (isDataOk)
            {
                e.Effects = DragDropEffects.Move;
                _dragDropEffects = e.Effects;
            }
            else
            {
                e.Effects = DragDropEffects.None;
                _dragDropEffects = e.Effects;
            }
        }

        private void flvTagEditor_FolderViewDragDrop(object sender, FolderViewDragDropEventArgs e)
        {
            var trackDragObject = (TrackDragObject)e.Data.GetData(typeof(TrackDragObject));

            List<Track> tracks = trackDragObject;
            string message = string.Empty;
            bool isFileOperationOk = false;

            if (_dragDropEffects == DragDropEffects.Move || _dragDropEffects == DragDropEffects.Copy)
            {
                try
                {
                    if (_dragDropEffects == DragDropEffects.Move)
                    {
                        isFileOperationOk = MoveFiles(tracks, e.Node.Path);

                        message = string.Format("Successfully moved {0} track(s) to\n\n{1}", tracks.Count, e.Node.Path);
                    }

                    if (_dragDropEffects == DragDropEffects.Copy)
                    {
                        isFileOperationOk = CopyFiles(tracks, e.Node.Path);

                        message = string.Format("Successfully copied {0} track(s) to\n\n{1}", tracks.Count, e.Node.Path);
                    }

                    RefreshTrackList(_currentPath);

                    flvTagEditor.RefreshTree();

                    if (isFileOperationOk)
                    {
                        MessageBox.Show(this, message, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    else
                    {
                        message = "There was a problem when moving or copying the selected track(s)";

                        MessageBox.Show(this, message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                }
                catch (Exception ex)
                {
                    message = string.Format("There was a problem when moving or copying the selected track(s)\n\n{0}", ex.Message);

                    MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        #endregion

        #region File Opreations.

        private bool MoveFiles(IEnumerable<Track> tracks, string destination)
        {
            var shellFileOperation = new ShellFileOperation();

            var source = new List<String>();
            var dest = new List<String>();

            foreach (var track in tracks)
            {
                source.Add(track.FullPath);
                dest.Add(Path.Combine(destination, track.FileName));
            }

            shellFileOperation.Operation = ShellFileOperation.FileOperations.FO_MOVE;
            shellFileOperation.OwnerWindow = Handle;
            shellFileOperation.SourceFiles = source;
            shellFileOperation.DestFiles = dest;
            shellFileOperation.ProgressTitle = "Moving Track(s)";

            return shellFileOperation.DoOperation();
        }

        private bool CopyFiles(IEnumerable<Track> tracks, string destination)
        {
            var shellFileOperation = new ShellFileOperation();

            var source = new List<String>();
            var dest = new List<String>();

            foreach (var track in tracks)
            {
                source.Add(track.FullPath);
                dest.Add(Path.Combine(destination, track.FileName));
            }

            shellFileOperation.Operation = ShellFileOperation.FileOperations.FO_COPY;
            shellFileOperation.OwnerWindow = Handle;
            shellFileOperation.SourceFiles = source;
            shellFileOperation.DestFiles = dest;
            shellFileOperation.ProgressTitle = "Copying Track(s)";

            return shellFileOperation.DoOperation();
        }

        private bool DeleteFiles(IEnumerable<Track> tracks)
        {
            var shellFileOperation = new ShellFileOperation();

            List<String> source = tracks.Select(track => track.FullPath).ToList();

            shellFileOperation.Operation = ShellFileOperation.FileOperations.FO_DELETE;
            shellFileOperation.OwnerWindow = Handle;
            shellFileOperation.SourceFiles = source;
            shellFileOperation.DestFiles = null;
            shellFileOperation.ProgressTitle = "Deleting Track(s)";

            return shellFileOperation.DoOperation();
        }

        #endregion

        #region Open db.etree.org Functions.

        private string CreateWebUrl(string shnid)
        {
            return string.Format("http://db.etree.org/shn/{0}", shnid);
        }

        private void txtShnId_Leave(object sender, EventArgs e)
        {
            while (bgwCheckUrl.CancellationPending)

                _timerCount = 1;

            if(bgwCheckUrl.IsBusy)
                return;

            if (string.IsNullOrEmpty(txtCatalog.Text))
            {
                _webUrl = string.Empty;
                icbCatalog.Enabled = true;
                txtCatalog.Enabled = icbCatalog.Checked;
                btnCheckWeb.Text = "Recording Info";
                tmrCheckWeb.Enabled = false;
            }
            else
            {
                _webUrl = CreateWebUrl(txtCatalog.Text);
                icbCatalog.Enabled = false;
                txtCatalog.Enabled = false;
                btnCheckWeb.Text = "Verifying Url";
                tmrCheckWeb.Enabled = true;
                bgwCheckUrl.RunWorkerAsync();
            }

            btnCheckWeb.Enabled = false;
        }

        private void tmrCheckWeb_Tick(object sender, EventArgs e)
        {
            btnCheckWeb.Text = string.Format("Verifying Url ({0:0#})", _timerCount);
            btnCheckWeb.Invalidate();
            _timerCount++;
        }

        private void bgwCheckUrl_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            btnCheckWeb.Enabled = false;

            e.Result = Functions.IsUrlAvailable(_webUrl); //Functions.CheckUrl(_webUrl);
        }

        private void bgwCheckUrl_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            tmrCheckWeb.Enabled = false;

            if ((bool)e.Result)
            {
                btnCheckWeb.Text = "Open URL";
                btnCheckWeb.Enabled = true;
            }
            else
            {
                btnCheckWeb.Text = "Not Verified";
                btnCheckWeb.Enabled = false;
            }

            txtCatalog.Enabled = true;

            icbCatalog.Enabled = true;
        }

        private void btnCheckWeb_Click(object sender, EventArgs e)
        {
            btnCheckWeb.Enabled = false;

            txtCatalog.Enabled = false;

            btnCheckWeb.Text = "Opening Url...";

            bgwOpenUrl.RunWorkerAsync();
        }

        private void bgwOpenUrl_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            btnCheckWeb.Enabled = false;

            e.Result = Functions.OpenUrl(_webUrl);
        }

        private void bgwOpenUrl_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            btnCheckWeb.Text = "Open URL";

            btnCheckWeb.Enabled = (bool)e.Result;

            txtCatalog.Enabled = true;
        }

        #endregion

        #region Copy And Paste Tags.

        private bool CheckClipboard()
        {
            if (ClipBoard.ContainsObject() && ClipBoard.GetObjectType() == typeof(TrackFlac))
            {
                return true;
            }

            return false;
        }

        private void PasteTag(Track track, bool noTitleField, bool noTrackField, bool noDiscField, bool noBpmField, bool noLyricsField, bool noArtistField)
        {
            var clipBoardTrack = (Track)ClipBoard.GetObject();

            if (noTitleField == false)
            {
                track.Title = clipBoardTrack.Title;
                track.IsTitleChanged = true;
            }

            if (noTrackField == false)
            {
                track.TrackNumber = clipBoardTrack.TrackNumber;
                track.IsTrackNumberChanged = true;
            }

            if (noDiscField == false)
            {
                track.DiscNumber = clipBoardTrack.DiscNumber;
                track.IsDiscNumberChanged = true;
            }

            if (noBpmField == false)
            {
                track.Bpm = clipBoardTrack.Bpm;
                track.IsBpmChanged = true;
            }

            if (noLyricsField == false)
            {
                track.Lyrics = clipBoardTrack.Lyrics;
                track.IsLyricsChanged = true;
            }

            if (noArtistField == false)
            {
                track.Artist = clipBoardTrack.Artist;
                track.IsArtistChanged = true;
            }

            track.Album = clipBoardTrack.Album;
            track.IsAlbumChanged = true;

            track.Albumartist = clipBoardTrack.Albumartist;
            track.IsAlbumArtistChanged = true;

            track.Year = clipBoardTrack.Year;
            track.IsYearChanged = true;

            track.Genre = clipBoardTrack.Genre;
            track.IsGenreChanged = true;

            track.Isrc = clipBoardTrack.Isrc;
            track.IsIsrcChanged = true;

            track.Comment = clipBoardTrack.Comment;
            track.IsCommentChanged = true;

            track.Originalartist = clipBoardTrack.Originalartist;
            track.IsOriginalArtistChanged = true;

            track.Copyright = clipBoardTrack.Copyright;
            track.IsCopyrightChanged = true;

            track.Url = clipBoardTrack.Url;
            track.IsUrlChanged = true;

            track.EncodedBy = clipBoardTrack.EncodedBy;
            track.IsEncodedByChanged = true;

            track.Catalog = clipBoardTrack.Catalog;
            track.IsCatalogChanged = true;

            track.Conductor = clipBoardTrack.Conductor;
            track.IsConductorChanged = true;

            track.Lyricist = clipBoardTrack.Lyricist;
            track.IsLyricistChanged = true;

            track.OriginalLyricist = clipBoardTrack.OriginalLyricist;
            track.IsOriginalLyricistChanged = true;

            track.Label = clipBoardTrack.Label;
            track.IsLabelChanged = true;

            track.RemixedBy = clipBoardTrack.RemixedBy;
            track.IsRemixedByChanged = true;

            track.RadioStationName = clipBoardTrack.RadioStationName;
            track.IsRadioStationNameChanged = true;

            track.AudioFileUrl = clipBoardTrack.AudioFileUrl;
            track.IsAudioFileUrlChanged = true;

            track.AuthorUrl = clipBoardTrack.AuthorUrl;
            track.IsAuthorUrlChanged = true;

            track.AudioSourceUrl = clipBoardTrack.AudioSourceUrl;
            track.IsAudioSourceUrlChanged = true;

            track.RadioStationUrl = clipBoardTrack.RadioStationUrl;
            track.IsRadioStationUrlChanged = true;

            track.BuyCdUrl = clipBoardTrack.BuyCdUrl;
            track.IsBuyCdUrlChanged = true;

            track.SetTags();
        }

        #endregion

        #region Playlist Creation.

        private void SavePlayList(IList<Track> tracks)
        {
            if (tracks.Count < 1)
                return;

            var frm = new FormPlaylist(tracks);

            DialogResult result = frm.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                string fileName = Functions.GetCurrentFolder(_currentPath);
                string text = frm.GetM3uText;

                if (string.IsNullOrEmpty(fileName))
                {
                    fileName = "Playlist.m3u";
                }

                saveFileDialog.InitialDirectory = _currentPath;
                saveFileDialog.Title = "Save selected files to .M3U playlist";
                saveFileDialog.Filter = "Play list file(*.m3u)|*.m3u";
                saveFileDialog.FileName = string.Format("{0}.m3u", fileName);

                DialogResult result1 = saveFileDialog.ShowDialog(this);

                if (result1 == DialogResult.OK)
                {
                    SaveM3uFile(saveFileDialog.FileName, text);
                }
            }
        }

        private void QuickSavePlayList(IList<Track> tracks)
        {
            if (tracks.Count < 1)
                return;

            string fileName = Functions.GetCurrentFolder(_currentPath);
            string text = Functions.CreatePlaylist(tracks);

            if (string.IsNullOrEmpty(fileName))
            {
                fileName = "Playlist.m3u";
            }
            else
            {
                fileName = fileName + ".m3u";
            }

            string path = Path.Combine(_currentPath, fileName);

            DialogResult result;

            if (File.Exists(path))
            {
                string message = string.Format("There are already a file named:\n\n{0}\n\nDo you want to overwrite the existing file?", path);

                result = MessageBox.Show(this, message, "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
            }
            else
            {
                result = DialogResult.Yes;
            }

            if (result == DialogResult.Yes)
            {
                if (SaveM3uFile(path, text))
                {
                    string message = string.Format("Playlist \"{0}\" successfully created", fileName);

                    MessageBox.Show(this, message, "Information", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
        }

        private bool SaveM3uFile(string path, string text)
        {
            StreamWriter streamWriter = null;

            try
            {
                streamWriter = new StreamWriter(path, false);

                streamWriter.Write(text);

                return true;
            }
            catch (Exception ex)
            {
                string message = string.Format("There was a problem saving the playlist file [{0}]\n\n{1}", path, ex.Message);

                MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                return false;
            }
            finally
            {
                if (streamWriter != null) streamWriter.Close();
            }
        }

        #endregion

        private void mnuViewReport_Click(object sender, EventArgs e)
        {
            var frm = new FormViewReport(_trackList.CheckedObjects);

            frm.ShowDialog(this);
        }

        private OLVColumn GetSortingColumnFromName(string value)
        {
            foreach (OLVColumn column in objectListView.AllColumns)
            {
                if(column.Tag.ToString() == value)
                {
                    return column;
                }
            }

            return objectListView.AllColumns[0];
        }

        private OLVColumn GetCheckedColumn()
        {
            foreach (ToolStripMenuItem item in mnuSecondSortColumn.DropDownItems)
            {
                if(item.Checked)
                {
                    //return (OLVColumn) item.Tag;
                    GetSortingColumnFromName(item.Text);
                }
            }

            return olvColumnFilename;
        }

        private void OnMenuSeconSortColumnClick(object sender, EventArgs e)
        {
            var item = (ToolStripMenuItem) sender;

            //var column = (OLVColumn) item.Tag;

            var column = GetSortingColumnFromName(item.Text);

            objectListView.SecondarySortColumn = column;

            foreach (ToolStripMenuItem mnu in mnuSecondSortColumn.DropDownItems)
            {
                mnu.Checked = false;
            }

            item.Checked = true;
        }

        private void CreateSecondarySortColumnMenu(OLVColumn col)
        {
            mnuSecondSortColumn.DropDownItems.Clear();

            foreach (OLVColumn column in objectListView.AllColumns)
            {
                var item = new ToolStripMenuItem(column.Tag.ToString(), null, (OnMenuSeconSortColumnClick));
                    //{Tag = column.Tag};

                mnuSecondSortColumn.DropDownItems.Add(item);

                if(column.Equals(col))
                {
                    item.Checked = true;
                }
            }
        }

        private void objectListView_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            //_cancelSorting = false;
        }

        //private void objectListView_ColumnClick(object sender, ColumnClickEventArgs e)
        //{
        //    objectListView.SecondarySortColumn = olvColumnFilename;
        //}
    }
}
